//
//  LcLocationClient.m
//  18Birdies
//
//  Created by weihua on 2017/6/26.
//  Copyright © 2017年 Lc. All rights reserved.
//

#import "LcLocationClient.h"
#import "LcLocationCenter.h"


@interface LcLocationCenter (hidden)

- (void)addDelegate:(id<LcLocationCenterDelegate>)delegate;
- (void)removeDelegate:(id<LcLocationCenterDelegate>)delegate;

- (void)startUpdating;
- (void)stopUpdating;

- (void)startUpdatingLocation;
- (void)stopUpdatingLocation;

- (void)startUpdatingHeading;
- (void)stopUpdatingHeading;

- (void)updateGpsAccuracyMode;

@end


@interface LcLocationClient () <LcLocationCenterDelegate>

@property(nonatomic, strong, readonly) LcLocationCenter* locationCenter;
@property(nonatomic, assign) BOOL updatingLocation;
@property(nonatomic, assign) BOOL updatingHeading;
@property(nonatomic, assign) BOOL locationPauseState;
@property(nonatomic, assign) BOOL headingPauseState;
@property(nonatomic, assign) BOOL isPause;

@end

@implementation LcLocationClient

+ (instancetype)client {
  return [[self alloc] init];
}

- (LcLocationCenter*)locationCenter {
  return [LcLocationCenter sharedInstance];
}

- (instancetype)init {
  self = [super init];
  if (self) {
    _useHighAccuracyMode = NO;
    [self.locationCenter addDelegate:self];
  }
  return self;
}

- (void)dealloc {
  [self stopUpdatingHeeading];
  [self stopUpdatingLocation];
  [self.locationCenter removeDelegate:self];
}

- (BOOL)usingGps {
  return self.updatingLocation && self.updatingHeading;
}

- (BOOL)authorized {
  return self.locationCenter.authorized;
}

- (BOOL)authorizationNotDetermined {
  return self.locationCenter.authorizationNotDetermined;
}

- (BOOL)locationEnabled {
  return self.locationCenter.locationEnabled;
}

- (CLLocation*)lastKnownLocation {
  return self.locationCenter.lastKnownLocation;
}

- (void)startUpdating {
  [self startUpdatingLocation];
  [self startUpdatingHeading];
}

- (void)stopUpdating {
  [self stopUpdatingLocation];
  [self stopUpdatingHeeading];
}

- (void)startUpdatingLocation {
  if (self.updatingLocation) {
    return;
  }
  self.updatingLocation = YES;
  [self.locationCenter startUpdatingLocation];
}

- (void)stopUpdatingLocation {
  if (!self.updatingLocation) {
    return;
  }
  self.updatingLocation = NO;
  [self.locationCenter stopUpdatingLocation];
}

- (CLHeading*)lastKnownHeading {
  return self.locationCenter.lastKnownHeading;
}

- (void)startUpdatingHeading {
  if (self.updatingHeading) {
    return;
  }
  self.updatingHeading = YES;
  [self.locationCenter startUpdatingHeading];
}

- (void)stopUpdatingHeeading {
  if (!self.updatingHeading) {
    return;
  }
  self.updatingHeading = NO;
  [self.locationCenter stopUpdatingLocation];
}

- (void)setUseHighAccuracyMode:(BOOL)useHighAccuracyMode {
  _useHighAccuracyMode = useHighAccuracyMode;
  [self.locationCenter updateGpsAccuracyMode];
}

- (void)pause {
  if (self.isPause) {
    return;
  }
  self.isPause = YES;
  self.locationPauseState = self.updatingLocation;
  self.headingPauseState = self.updatingHeading;
  [self stopUpdating];
}

- (void)resume {
  if (!self.isPause) {
    return;
  }
  self.isPause = NO;
  if (self.locationPauseState) {
    [self startUpdatingLocation];
  }
  if (self.headingPauseState) {
    [self startUpdatingHeading];
  }
}

// MARk: - LcLocationCenterDelegate
- (void)onLocationChanged:(CLLocation*)location {
  if (self.updatingLocation && [self.delegate respondsToSelector:_cmd]) {
    [self.delegate onLocationChanged:location];
  }
  if (self.requestLocationOneTime) {
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
      [self stopUpdatingLocation];
    }];
  }
}

- (void)onHeadingChanged:(CLHeading*)heading {
  if (self.updatingHeading && [self.delegate respondsToSelector:_cmd]) {
    [self.delegate onHeadingChanged:heading];
  }
}

- (void)onLocationAuthorizedChanged:(BOOL)authorized {
  if ([self.delegate respondsToSelector:_cmd]) {
    [self.delegate onLocationAuthorizedChanged:authorized];
  }
}

@end
